using System;

namespace Tycho.Parser.Peg {
    public abstract class Rule : IRule {
        public virtual RuleParseResult Parse(char[] source, int index, ParseContext context, string sourceString, ParseEnvironment environment)
        {
            RuleParseResult result = null;
            Func<RuleParseResult, Yield> continuation = r =>
            {
                result = r;
                return null;
            };
            Yield yield = Parse(source, index, context, sourceString, environment, continuation);
            ExecuteYields(yield);
            return result;
        }

        void ExecuteYields(Yield yield)
        {
            while (yield != null)
            {
                yield = yield();
            }
        }

        public virtual Yield Parse(char[] source, int index, ParseContext context, string sourceString, ParseEnvironment environment, Func<RuleParseResult, Yield> continuation)
        {
            return () => continuation(Parse(source, index, context, sourceString, environment));
        }

        public virtual bool IsInfix {
            get {
                return false;
            }
        }

        public virtual IInfixInformation InfixInformation {
            get { return new NotInfixInformation (); }
        }

        public virtual bool HasProduction {
            get { return false; }
        }

        public virtual IProduction Production {
            get { return null; }
            set { throw new InvalidOperationException (); }
        }
    }
}